package com.irdstudio.apicenter.gateway.web.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;

import com.irdstudio.apicenter.gateway.comm.MaccsPacket;
import com.irdstudio.apicenter.gateway.security.auth.AuthManager;
import com.irdstudio.apicenter.gateway.security.auth.ClientInfo;
import com.irdstudio.apicenter.gateway.web.MaccsException;
import com.irdstudio.apicenter.gateway.web.MaccsTradeDefineVo;
import com.irdstudio.apicenter.gateway.web.view.JsonView;
import com.irdstudio.apicenter.gateway.web.view.View;


/**
 * APP应用端启动时安全检查
 * 及版本检查（暂未实现)
 * @author guangming.li
 * @version 1.0
 * @date 2015-05-27
 */

@Controller
public class ClientInit implements IController {

	private static final Logger log = LoggerFactory
			.getLogger(ClientInit.class);

	@SuppressWarnings("unchecked")
	public View execute(MaccsTradeDefineVo tradeDefine, MaccsPacket inPacket,
			HttpServletRequest request, HttpServletResponse response)
			throws MaccsException {
		
		Object reultData = null;
		/* 获取设备ID，第一步，第二步 */
		String did = inPacket.getValue("d");
		/* 获取设备类型标识,android,ios */
		String p = inPacket.getValue("p");
		/* 获取md5后的随机数，第一步。第二步，在第一次随机数md5的基础上再次md5 */
		String random = inPacket.getValue("r");
		/* 渠道码，第二步 */
		String chanel = inPacket.getValue("c");
		/* 第三步骤传递,客户端完整性校验,加密后字符串：资源文件hash值+签名信息+设备id+版本号 */
		String encryptMsg = inPacket.getValue("e");
		String sourceip = inPacket.getValue("sourceip");
		if (chanel.isEmpty() && encryptMsg.isEmpty()) {
			// 第一回合，服务端记录该随机数及会话信息
			reultData = sayHello(did, sourceip, random,request);
		} else if (!chanel.isEmpty() && encryptMsg.isEmpty()) {
			// 第二回合
			reultData = shakeHand(did, random, chanel,request);
		} else if (!encryptMsg.isEmpty()) {
			// 第三回合,待实现
			try {
				reultData = checkIntegrity(request, did, encryptMsg);
			} catch (Exception e) {
				log.error("Process Error:", e);
				e.printStackTrace();
			}
		}
		return new JsonView(request, response, new MaccsPacket(
				(Map<String, Object>) reultData));
	}

	/**
	 * 向服务端注册客户端信息
	 * 放入到request的session对象中n
	 * @param did
	 * @param sourceip
	 * @param random
	 * @param request
	 * @return
	 */
	private Object sayHello(String did, String sourceip, String random,HttpServletRequest request) {
		AuthManager.initClient(did, sourceip, random,request);
		Map<String, Object> backData = new HashMap<String, Object>();
		backData.put("ec", "0");
		backData.put("em", " ");
		return backData;
	}

	// 尝试握手
	private Object shakeHand(String did, String random, String channel,HttpServletRequest request) {
		int v = AuthManager.validClient(did, random);
		Object result;
		if (v == 0) {
			String toke = AuthManager.genToken();
			ClientInfo c = AuthManager.getClientInfo(request);
			c.setToken(toke);
			result = getToken(toke);
		} else if (v == 1) {
			// 不合法客户端
			result = getError("1003", "无效客户端ID");
		} else {
			// 校验失败
			result = getError("1004", "无效随机数");
		}
		ClientInfo c = AuthManager.getClientInfo(request);
		c.setChannel(channel);
		return result;
	}

	// 校验客户端完整性
	private Object checkIntegrity(HttpServletRequest request, String did,
			String encryptMsg) throws Exception {
//		ClientInfo c = AuthManager.getClientInfo(request);
//		// 解密以后的字符串格式为：资源文件hash值+签名信息+设备id+Native版本号+web版本号
//		// 如：fb459fa9a4dd803ebcc788ef236c33b5+com.citic.iphone+84:38:35:4A:3A:A8+1.01
//		String[] msg = null;
//
//		msg = ThreeDesUtil.decryptThreeDESECB(c.getToken(), encryptMsg).split(
//				"\\+");
//		String hash = msg[0];
//		String apkSign = msg[1];
//		String webVersion = msg[4];
//		String apkVersion = msg[3];
//		if (!msg[2].equals(did)) {
//			return getError("1005", "设备ID数据无效");
//		}
//		ClientInfo clientInfo = AuthManager.getClientInfo(request);

//		// 如果是android，则校验apk签名信息
//		if (isAndroid(clientInfo.getChannel())) {
//			Apk apk = apkManager.getVerByVid(new Long(apkVersion));
//			if (apk == null ) {
//				log.error("Client's Apk Version not found:"+apkVersion+", clientinfo->[did:" + clientInfo.getDid()+ ",IP:" + clientInfo.getIp() + "]");
//				if(!MaccsConstant.Client_debug_mode)
//				return getError("1008", "APK文件未初始化");
//			} else if (!apk.getSign().equals(apkSign)) {
//				log.error("Apk signData check Fail, client signdata:" + apkSign+" server signdata:"+apk.getSign()+", clientinfo->[did:" + clientInfo.getDid()+ ",IP:" + clientInfo.getIp() + "]");
//				if(!MaccsConstant.Client_debug_mode)
//				return getError("1007", "APK文件校验失败");
//			}
//		}
//				
//		WebResource wr_max = webResourceManager.getMaxVer();
//		WebResource wr_client = webResourceManager.getVerByVid(new Long(
//				webVersion));
//		if (wr_max == null) {
//			//如果没有最大版本，则系统未上传初始版本
//			if (wr_max == null)
//				log.warn("WebResource Not Found->" + " maxVersion"+", clientinfo->[did:" + clientInfo.getDid()+ ",IP:" + clientInfo.getIp() + "]");
//			if (wr_client == null)
//				log.warn("WebResource Not Found:" + webVersion+", clientinfo->[did:" + clientInfo.getDid()+ ",IP:" + clientInfo.getIp() + "]");
//			if (!MaccsConstant.Client_debug_mode)
//				return getError("1007", "系统资源未初始化");
//		}
//		
//		if (wr_client == null&&wr_max!=null&&(Long.valueOf(webVersion) > wr_max.getVid().longValue())) {
//			//客户端版本找不到，并且客户端版本大于服务端最大版本
//			// 客户端已更新了服务端回退版本的代码，此时需要获取最新的全量版本
//			Version	v = getFullVersion(wr_max, request);
//			return getVersion(v);
//		}
//		
//
//		if (wr_client != null && !hash.equals(wr_client.getHash())) {
//			log.error("WebResource check Fail, Client Hash :" + hash + " not equal server Hash:"
//					+ wr_client.getHash()+", clientinfo->[did:" + clientInfo.getDid()+ ",IP:" + clientInfo.getIp() + "]");
//			if (!MaccsConstant.Client_debug_mode)
//			{
//				return getVersion(getFullVersion(wr_max, request));
//			}
//		}
//		
//		Version v = getVersion(apkVersion, new Long(webVersion), wr_max,
//				clientInfo.getChannel(), request);
		// Object result=null;
		return getVersion(new Version());
	}

	private boolean isAndroid(String chanel) {
		boolean is = false;
		if (("1202").equals(chanel) || ("1204").equals(chanel)) {
			is = true;
		}
		return is;

	}

	private boolean isIOS(String chanel) {
		boolean is = false;
		if (("1201").equals(chanel) || ("1203").equals(chanel)) {
			is = true;
		}
		return is;

	}

//	private Version getVersion(String apkVersion, Long clientVersion,
//			 String chanel, HttpServletRequest request) {
//		Version v = new Version();
//		if (apkVersion != null && isAndroid(chanel)) {
//			Apk apk = apkManager.getMaxVer();
//			if (apk != null
//					&& apk.getVid().longValue() > Long.parseLong(apkVersion)) {
//				v.setApkForce(apk.getForceUpdate());
//				v.setApkPath(getApkUrl(apk, request));
//				v.setApkSize(apk.getVsize());
//				v.setApkVersion(apk.getVid().toString());
//			}
//		}
//		// 客户端请求过来，带上参数version，获取webresource当前最大max_vid版本，
//		// 如果version等于max_vid不处理
//		// 如果version大于max_vid，则要回滚版本，取max_vid对应的baseline版本(查询vid=baseline），如果baseline为空，则取max_vid版本。
//		// 如果version小于max_vid且（大于或等于）baseline，则根据max_vid和version从webresource_fix获取相应版本信息。
//		// 如果version小于max_vid且小于baseline（做了全量版本合并），则从webresource取合并版本信息（vid为baseline的版本信息），（注意这样情况下，返回的信息中版本为最大vid值，因为做了全量版本更新，url为http://xxxx/upload/baseline/full_vid.zip）。
//		// 返回包含：版本，url，size，是否强制更新，版本类型（fix，full，如果是full需要先把之前的目录删除然后在解压）
//		if (wr_max == null)
//			return v;
//		if (wr_max.getVid().longValue() == clientVersion.longValue()) {
//			return v;
//		}
//
//		Long baseline = wr_max.getBaseline();
//		if (baseline == null)
//			baseline = wr_max.getVid();
//
//		/*if (clientVersion.longValue() > wr_max.getVid().longValue()) {
//			// 回退
//			v = getFullVersion(wr_max, request);
//		} else*/ if (clientVersion.longValue() < wr_max.getVid().longValue()) {
//			if (clientVersion.longValue() >= baseline.longValue()) {
//				WebResourceIncr inc = webResourceManager.getIncrVer(
//						wr_max.getVid(), new Long(clientVersion));
//				v.setWebFull("0");// 0：部分更新，1：全量更新
//				v.setWebPath(getResourceUrl(wr_max, inc, request));
//				v.setWebSize(inc.getVsize());
//				v.setWebVersion(String.valueOf(inc.getVid()));
//				// 强制升级 1
//				// 不强制升级 0
//				// APK强制升级 2
//				// IOS强制升级 3
//				// 赞不处理多版本区别
//				v.setWebForce(inc.getForceUpdate());
//				if (Integer.parseInt(inc.getVsize()) <= MaccsConstant.direct_update_size)
//					v.setWebUpdatePrompt("0");
//			} else {
//				// 客户端小于baseline，直接更新到全量的baseline
//				v = getFullVersion(wr_max, request);
//			}
//		}
//		return v;
//
//	}

	private Object getToken(String token) {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("ec", "0");
		m.put("em", "");
		m.put("token", token);
		return m;
	}

//	private Version getFullVersion(WebResource wr, HttpServletRequest request) {
//		Version v = new Version();
//		v.setWebFull("1");
//		v.setWebVersion(String.valueOf(wr.getVid()));
//		v.setWebSize(wr.getVsize());
//		v.setWebForce("1");
//		v.setWebPath(getResourceUrl(wr, request));
//		return v;
//	}

//	private String getResourceUrl(WebResource wr, HttpServletRequest request) {
//		synchronized (Lock) {
//			if (wr.getFullUrl() == null) {
//				String filePath = request.getSession().getServletContext()
//						.getRealPath("/")
//						+ MaccsConstant.UPLOAD_PATH + "/" + wr.getBaseline();
//				String fileName = "full_" + wr.getBaseline() + ".zip";
//				getFile(wr.getResourceData(), filePath, fileName);
//				String url = MaccsConstant.MOBILE_SERVER_URL
//						+ MaccsConstant.UPLOAD_PATH + "/" + wr.getBaseline() + "/"
//						+ fileName;
//				wr.setFullUrl(url);
//				webResourceManager.saveOrUpdate(wr);
//				return url;
//			} else {
//				return wr.getFullUrl();
//			}
//		}
//
//	}

//	private String getResourceUrl(WebResource wr, WebResourceIncr wr_incr,
//			HttpServletRequest request) {
//		synchronized (Lock) {
//			if (wr_incr.getUrl() == null) {
//				String filePath = request.getSession().getServletContext()
//						.getRealPath("/")
//						+ MaccsConstant.UPLOAD_PATH + "/" + wr.getBaseline();
//				String fileName = "fix_" + wr_incr.getIncreamentvid() + "_"
//						+ wr_incr.getVid() + ".zip";
//				getFile(wr_incr.getResourceData(), filePath, fileName);
//				String url = MaccsConstant.MOBILE_SERVER_URL
//						+ MaccsConstant.UPLOAD_PATH + "/" + wr.getBaseline() + "/"
//						+ fileName;
//				wr_incr.setUrl(url);
//				webResourceIncrManager.saveOrUpdate(wr_incr);
//				return url;
//			} else {
//				return wr_incr.getUrl();
//			}
//		}
//
//	}

//	private String getApkUrl(Apk apk, HttpServletRequest request) {
//		synchronized (Lock) {
//			if (apk.getUrl() == null) {
//				String filePath = request.getSession().getServletContext()
//						.getRealPath("/")
//						+ MaccsConstant.UPLOAD_PATH + "/";
//				getFile(apk.getResourceData(), filePath, apk.getFileName());
//				String url = MaccsConstant.MOBILE_SERVER_URL
//						+ MaccsConstant.UPLOAD_PATH + "/" + apk.getFileName();
//				apk.setUrl(url);
//				apkManager.saveOrUpdate(apk);
//				return url;
//			} else {
//				return apk.getUrl();
//			}
//		}
//
//	}

	public static void getFile(byte[] bfile, String filePath, String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			File dir = new File(filePath);
			if (!dir.exists()) {// 判断文件目录是否存在
				dir.mkdirs();
			}
			file = new File(filePath + "\\" + fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bfile);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	private Object getVersion(Object obj) {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("ec", "0");
		m.put("em", "");
		m.put("version", obj);
		return m;
	}

	public class Version {
		private String apkVersion;
		private String apkSize;
		private String apkPath;
		private String apkForce;

		private String webVersion;
		private String webSize;
		private String webPath;
		private String webForce;
		private String webFull = "0"; // 0：增量，1：全量
		private String webUpdatePrompt = "1";// 1:提示，0，不提示

		public String getWebUpdatePrompt() {
			return webUpdatePrompt;
		}

		public void setWebUpdatePrompt(String webUpdatePrompt) {
			this.webUpdatePrompt = webUpdatePrompt;
		}

		public String getWebFull() {
			return webFull;
		}

		public void setWebFull(String webFull) {
			this.webFull = webFull;
		}

		public String getApkVersion() {
			return apkVersion;
		}

		public void setApkVersion(String apkVersion) {
			this.apkVersion = apkVersion;
		}

		public String getApkSize() {
			return apkSize;
		}

		public void setApkSize(String apkSize) {
			this.apkSize = apkSize;
		}

		public String getApkPath() {
			return apkPath;
		}

		public void setApkPath(String apkPath) {
			this.apkPath = apkPath;
		}

		public String getApkForce() {
			return apkForce;
		}

		public void setApkForce(String apkForce) {
			this.apkForce = apkForce;
		}

		public String getWebVersion() {
			return webVersion;
		}

		public void setWebVersion(String webVersion) {
			this.webVersion = webVersion;
		}

		public String getWebSize() {
			return webSize;
		}

		public void setWebSize(String webSize) {
			this.webSize = webSize;
		}

		public String getWebPath() {
			return webPath;
		}

		public void setWebPath(String webPath) {
			this.webPath = webPath;
		}

		public String getWebForce() {
			return webForce;
		}

		public void setWebForce(String webForce) {
			this.webForce = webForce;
		}

	}

	private static Object Lock = new Object();

	public static void del(String filepath) {
		try {
			File f = new File(filepath);// 定义文件路径
			if (f.exists() && f.isDirectory()) {// 判断是文件还是目录
				if (f.listFiles().length == 0) {// 若目录下没有文件则直接删除
					f.delete();
				} else {// 若有则把文件放进数组，并判断是否有下级目录
					File delFile[] = f.listFiles();
					int i = f.listFiles().length;
					for (int j = 0; j < i; j++) {
						if (delFile[j].isDirectory()) {
							del(delFile[j].getAbsolutePath());// 递归调用del方法并取得子目录路径
						}
						delFile[j].delete();// 删除文件
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String args[]) {
		del("C:/aa");
	}
	
	protected Map<String, Object> getError(String code, String msg) {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("ec", code);
		m.put("em", msg);
		return m;
	}	
}
